using TFlex.Model;
using TFlex.Model.Model3D.Geometry;
using TFlex.Model.Model3D.Visual;

namespace External3D
{
	// Base manipulator class
	//
	// Базовый класс манипуляторов
	public class BaseManipulator
	{
		// Tolerance for various calculations
		//
		// Точность вычислений
		public const double Epsilon = 1.0e-6;

		// Offset of the manipulator dialog relative to the mouse cursor
		//
		// Смещение диалогового окна манипулятора относительно курсора мыши
		public const int DialogOffset = 5;

		protected static readonly Direction m_xAxis = new Direction(1.0, 0.0, 0.0);
		protected static readonly Direction m_yAxis = new Direction(0.0, 1.0, 0.0);
		protected static readonly Direction m_zAxis = new Direction(0.0, 0.0, 1.0);

		protected Document m_document = null;

		protected DecorationManager m_decorationManager = null;

		// Application which created this manipulator
		//
		// Экземпляр класса внешнего приложения
		protected External3DPlugin m_plugin = null;

		// Measurement unit converter
		//
		// Конвертер единиц измерения документа в метры и из метров
		protected UnitConverter m_converter = null;

		// Current value of this manipulator
		//
		// Текущее значение манипулятора
		protected ManipulatorValue m_value = null;

		// Constructs a manipulator
		//
		// Конструктор
		public BaseManipulator(Document document, External3DPlugin plugin)
		{
			m_document = document;
			m_decorationManager = DecorationManager.GetManager(m_document);
			m_plugin = plugin;
			m_converter = new UnitConverter(m_document);
		}

		// Activates this manipulator
		//
		// Запустить манипулятор
		protected void StartDialog()
		{
			if (m_value != null)
				return;

			m_value = new ManipulatorValue();
			m_value.Show();
		}

		// Makes the dialog display the current state of this manipulator
		//
		// Изменить значения драггера
		protected void UpdateDialog(double val, int x, int y)
		{
			if (m_value == null)
				StartDialog();

			m_value.Value = val;
			m_value.Left = x;
			m_value.Top = y;
		}

		protected void UpdateDialog(double val, System.Drawing.Point cursorPosition)
		{
			UpdateDialog(val, cursorPosition.X + DialogOffset, cursorPosition.Y + DialogOffset);
		}

		// Deactivates this manipulator
		//
		// Остановить манипулятор
		protected void StopDialog()
		{
			if (m_value == null)
				return;

			m_value.Close();
			m_value.Dispose();
			m_value = null;
		}

		// Event triggered when the user starts using this manipulator
		//
		// Событие активизации манипулятора
		public delegate void ManipulatorActivated(IDManipulator manipulator);
		public event ManipulatorActivated Activated;
		protected void BaseActivated(IDManipulator manipulator)
		{
			if (Activated != null)
				Activated(manipulator);
		}

		// Event triggered when the user changes the state of this manipulator
		//
		// Событие изменения параметров манипулятора
		public delegate void ManipulatorUpdated(IDManipulator manipulator);
		public event ManipulatorUpdated Updated;
		protected void BaseUpdated(IDManipulator manipulator)
		{
			if (Updated != null)
				Updated(manipulator);
		}

		// Event triggered when the user finishes using this manipulator
		//
		// Событие завершения изменения параметров манипулятора
		public delegate void ManipulatorReleased(IDManipulator manipulator);
		public event ManipulatorReleased Released;
		protected void BaseReleased(IDManipulator manipulator)
		{
			if (Released != null)
				Released(manipulator);
		}

		// Type of object parameter handled by this manipulator
		//
		// Тип изменения манипулятора
		public enum IDManipulator
		{
			// Point coordinates
			//
			// Изменились координаты точки
			Point,

			// Orientation in global coordinate system
			//
			// Изменилась ориентация в пространстве
			Orientation,

			// Linear size
			//
			// Линейный размер
			Linear
		};
	};
}
